/*
 * ContainerPanel.java
 * 
 * @version 1.0, April 28, 2011
 * CS 2340 Team 10: Cyberdyne Systems
 */
package edu.gatech.oad.cyberdoc.view.container;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import org.json.JSONObject;

import edu.gatech.oad.cyberdoc.view.ApplicationPanel;

/**
 * Defines the common elements of a class that serves as one of the main panels
 * in our GUI.
 * 
 * @author John Girata
 * @version 1.0, April 28, 2011
 */
public abstract class ContainerPanel extends ApplicationPanel {
	/**
	 * This class's logger.
	 */
	private static final Logger LOG;

	/**
	 * The ApplicationPanels contained within this panel.
	 */
	private Map<String, ApplicationPanel> cards;

	/**
	 * The JPanel that serves as the holder for the cards.
	 */
	private JPanel holder;

	/**
	 * The default text to show the user.
	 */
	protected JLabel textLabel;

	/**
	 * A map containing the cards in the card layout.
	 */
	protected Map<String, String> map;

	static {
		LOG = Logger.getLogger("edu.gatech.oad.cyberdoc.view.PatientPanel");
	}

	/**
	 * Creates a new ContainerPanel with the menu and default text.
	 * 
	 * @param menu
	 *            The panel's menu
	 * @param text
	 *            The panel's default text
	 */
	public ContainerPanel(JPanel menu, String text) {
		setLayout(new BorderLayout(12, 0));

		cards = new HashMap<String, ApplicationPanel>();

		holder = new JPanel();
		add(holder, BorderLayout.CENTER);
		holder.setLayout(new CardLayout(0, 0));

		if (menu != null) {
			add(menu, BorderLayout.WEST);
		}

		if (text == null) {
			text = "<html>Welcome to Cyberdoc, the medical office management "
					+ "system.  To begin, choose an option from the list on "
					+ "the left.</html>";
		}

		final JPanel def = new JPanel();
		def.setLayout(new BoxLayout(def, BoxLayout.Y_AXIS));

		textLabel = new JLabel(text);
		textLabel.setVerticalAlignment(SwingConstants.TOP);
		def.add(textLabel, BorderLayout.CENTER);

		setDefaultPanel(def);

		map = new HashMap<String, String>();
	}

	/**
	 * Creates a new ContainerPanel with no default text.
	 * 
	 * @param menu
	 *            The panel's menu
	 */
	public ContainerPanel(JPanel menu) {
		this(menu, null);
	}

	/**
	 * Creates a new ContainerPanel with no menu.
	 */
	public ContainerPanel() {
		this(null);
	}

	public final void setDefaultPanel(JPanel def) {
		holder.add(def, "default");
	}

	public final void addCard(String key, ApplicationPanel panel) {
		holder.add(panel, key);
		cards.put(key, panel);
	}

	/**
	 * Allows the same panel to be shown in response to multiple "next" commands
	 * from the server.
	 * 
	 * Each command can only be mapped to one other command, but a command can
	 * be mapped to from multiple commands. Commands cannot be chained.
	 * 
	 * @param from
	 *            The command to be handled by another command
	 * @param to
	 *            The command responding to multiple commands
	 */
	public final void map(String from, String to) {
		map.put(from, to);
	}

	/**
	 * Displays the requested panel.
	 * 
	 * @param panel
	 *            The panel to show
	 * @param response
	 *            Useful information from the server
	 */
	public void show(String panel, JSONObject response) {
		LOG.info("Showing panel " + panel);

		final CardLayout layout = (CardLayout) holder.getLayout();
		layout.show(holder, panel);

		if (map.containsKey(panel)) {
			final String redirect = map.get(panel);
			LOG.info("Redirecting panel " + panel + " to " + redirect);
			panel = redirect;
		}

		if (cards.containsKey(panel)) {
			cards.get(panel).show(response);
		} else {
			LOG.warning("No such panel \"" + panel + "\"");
		}
	}
}
